home *** CD-ROM | disk | FTP | other *** search
Wrap
/*************************************************/ /* CRUd error (header)"); QBBSe eility (header)"); (headeDelete old messages in a Pandora message base (header)"); (heade Written by Vincent Pomey, 30 july 1992 (header)"with parts of Jac Kersing's code (header)"); (head*****************/ /* CRUd error (he #define MAILER adeneeded in PANDORA.H (he #include "pandora.h" adefor structure of the area's etc. (he #include "utextra.pro" #include "crunch.pro" #define UVERSION "1.22" adeVersion number of this eility (he#define LASTMOD __DATE__e#define BUFFERSIZ 100L adesize in kbyte of the buffer (he#define MAXINT 32500 #define DEBUG 0 adeDisplay extended (debugging) info? (he#define LEDe#define QBBSeadeDefinitions of global variables first (he typedef unsigned long ulong; char progname[]="B-C"; adeprogram nameefor logging (hechar *Bpath=""; adepathefor config file (he char *AreaPath[N_AREAS]; adepatheto message area (hechar *AreaName[N_AREAS]; adenameeof area (hestruct akeep { int days, min, max; } *AreaKeep[N_AREAS],eDefKeep; #ifdef LEDeint *AreaLed, *AreaLedFlags;echar *ledfile; #endif eint msgareas; adenumber of messageareas (heint verbose=6; adelevelefor message displaying (heint loglevel; adelevelefor message logging (hechar *logname; adenameeof logfile (hechar *netpath=NULL; adepatheto netmail area (heFILE *log; adefilepointer for logfile (he#ifdef QBBSeFILE *qbbs; #endif #ifdef LEDeFILE *led; adelastread pointers for QuickBBS and Led (he#endif eadeOk, so far all definitions. The program is next.. (he void (myalloc(sp) size_t sp; { char *tmp; tmp=malloc(sp); if (tmp==NULL) { message(6,"!Mem error"); exit(1); } return tmp; }e char *skip_blanks(string) char *string; { while (*string && isspace(*string)) ++string; return string; }e char *skip_to_blank(string) char *string; { while (*string && !isspace(*string)) ++string; return string; }e char *ctl_string(string) char *string; { char *p, *d; p=skip_blanks(string); d=malloc(strlen(p)+1); if(d==NULL) { message(6,"!Mem error"); return ""; } strcpy(d,p); return d; }e char *ctl_path(string) char *string; { char *p, *d, db[80]; p=skip_blanks(string); d=skip_to_blank(string); *d='\0'; if (strlen(p)>78) { message(6,"!Pathetoo long (%s)",p); return ""; } strcpy(db,p); #if UNIX if (db[strlen(db)-1]!='/') strcat(db,"/"); #else if (db[strlen(db)-1]!='\\') strcat(db,"\\"); #endif return ctl_string(db); }e void sprintb(char *b, char *f, char *n) { if (n[strlen(n)-1]!=DIRSEP) { strcpy (b, n); #ifdef UNIX strcat (b, "/"); #else strcat (b, "\\"); #endif strcat (b, f); } else { strcpy (b, n); strcat (b, f); } }e int init_conf(void) { FILE *conf; adefilepointer for config-file (he char buffer[256]; adebuffer for 1 line (he char *p; adeworkhorse (he int count; adejust a counter... (he char *ffirst(); adedirectoryefind (he char *getenv(); adeget the environment string (he p=getenv("MAILER"); if (!ffirst("bermuda.cfg") && adecheck local config (he !ffirst("tb.cfg") &&e p!=NULL && *p!='\0') { adeno local, and envi contained one (he Bpath= ctl_path(p); } sprintf(ebuffer, "%sbermuda.cfg", Bpath); conf= fopen(buffer, "r"); if (conf==NULL) { sprintf(buffer,"%stb.cfg", Bpath); conf = fopen(buffer, "r"); } if (conf==NULL) adeopen config-file (he { message(6,"!Configuration file not found, please check!!!"); return 1; adenot found, back (he } adeset all to default values (he e loglevel=255; message(-1,"+Parsing configuration file"); while((fgets(buffer, 250, conf))) aderead a line (he { p=skip_blanks(buffer); if (*p==';') continue; adecomment?? (he adedelete ALL chars following (and inclusive)ecomment sign (he if ((p=strchr(buffer,';'))!=NULL) *p= '\0'; if ((count= (int)strlen(buffer))<3) continue; adewhat's the lengtheof the rest? (he p= &buffer[--count]; if (*p=='\n') *p=0; adedelete (possible) newline char *he #ifdef LINN adeprocess "application bermuda" lines as normal lines (he if (!strnicmp(buffer,"application",11))e { p=skip_blanks(&buffer[11]); if(!strnicmp(p,"bermuda",7)) { p=skip_blanks(&p[7]); strcpy(buffer,p); } }e#endif e if (!strnicmp(buffer,"netmail",7))e { netpath=ctl_string(&buffer[7]); continue; } e if (!strnicmp(buffer,"loglevel",8))e { p=skip_blanks(&buffer[8]); if (sscanf(p,"%d", &count)!=1 || count>6 || count<0) message(3,"-Invalid loglevel (%s)", p); else loglevel=count; continue; } e if (!strnicmp(buffer, "statuslog",9))e { logname= ctl_string(&buffer[9]); if ((log=fopen(logname, "a"))==NULL) if ((log=fopen(logname, "w+"))==NULL) { message(6,"!Couldenot create logfile!"); free(logname); logname=NULL; } else { fflush(log); } continue; } } fclose(conf); return 0; adesignal OK (he} e void init(argc, argv) adeinitialize everything needed (heint argc; adecounter (hechar *argv[]; adecommandline crap (he{e int i; adecounter (he char *p, *q; adenice pointers.. (he char buffer[300]; adeto store lines from AREAS.BBS etc. in (he char temp[80]; adetemp. storage (he char areasbbs[80]; adenameeof file for AREAS.BBS (he FILE *fd; adefile descriptor for control and areas.bbs (he long atol(); strcpy(areasbbs, "areas.bbs"); adedefault namee(he if (init_conf()) exit(2); adefirst parse config file (he DefKeep.days=30; DefKeep.min=0; DefKeep.max=MAXINT; for (i=1;i<argc;i++) adeparse commandline arguments (he { if (argv[i][0]=='-')e { switch (toupper(argv[i][1])) { case 'D': DefKeep.days=atoi(&argv[i][2]); break; case 'M': DefKeep.min =atoi(&argv[i][2]); break; case 'X': DefKeep.max =atoi(&argv[i][2]); break; default: message(6,"!Unknowneoption %s",argv[i]); } } else strncpy(areasbbs,argv[i],79); } for (i=0; i<N_AREAS; i++) AreaKeep[i]=&DefKeep; adeset the default (he msgareas=0; sprintf(buffer,"%s%s", Bpath, areasbbs); if((fd=fopen(buffer, "r"))==NULL) { message(6,"-Cannot open %s, aborting...",buffer); exit(2); } adeget the MAIN origin line (he do fgets(buffer,299,fd); while (buffer[0]=='-' || buffer[0]==';') ; while (fgets(buffer,299,fd)) adenext line (he { q=skip_blanks(buffer); if (!*q || *q==';') continue; adecomment line? (he if (strlen(q)<5) continue; if (msgareas >= N_AREAS) { message(6,"!Too many areas, only %d allowed\n", N_AREAS); exit(2); } adeprocess option lines, and modify the default (he if (*q=='-')e { if (!(strnicmp (q+1, "days", 4))) { AreaKeep[msgareas]=myalloc (sizeof (struct akeep)); AreaKeep[msgareas]->min=0; AreaKeep[msgareas]->max=MAXINT; q=skip_blanks(skip_to_blank(q)); p=skip_to_blank(q); adeq :efirst, p :esecond (he e if (*p==0) AreaKeep[msgareas]->days=atoi(q); else { *p++=0; AreaKeep[msgareas]->days=atoi(q); while (1) { p=skip_blanks(p); if (*p==0) break; if (!strnicmp (p, "max", 3)) { q=skip_blanks(skip_to_blank(p)); p=skip_to_blank(q); if (*p==0) { AreaKeep[msgareas]->max=atoi(q); break; } else { *p++=0; AreaKeep[msgareas]->max=atoi(q); } } else if (!strnicmp (p, "min", 3)) { q=skip_blanks(skip_to_blank(p)); p=skip_to_blank(q); if (*p==0) { AreaKeep[msgareas]->min=atoi(q); break; } else { *p++=0; AreaKeep[msgareas]->min=atoi(q); } } } adewhile (he } continue; } if (!(strnicmp (q+1, "msgs", 4))) { AreaKeep[msgareas]=myalloc (sizeof (struct akeep)); q=skip_to_blank(q); q=skip_blanks(q); p= q+strlen(q)-1; while (isspace(*p) || !*p) *p--=0; AreaKeep[msgareas]->max=atoi(q); AreaKeep[msgareas]->days=MAXINT; AreaKeep[msgareas]->min=0; continue; } continue; } for (p=temp; *q && !isspace(*q); *p++=*q++) ; *p=0; if (!stricmp(temp,"PASSTHRU")) continue; AreaPath[msgareas]=ctl_string(temp); adecopyepatheto area (he while (isspace(*q)) q++; for (p=temp; *q && !isspace(*q); *p++=*q++) ; *p=0; if (!stricmp(temp,"MAIL")) { netpath=NULL; adewon't add a netmail area later (he strcpy (temp, "FidoNetmail"); } AreaName[msgareas]=ctl_string(temp); adecopyenameeof area *he #if DEBUG printf ("area=%s days=%d min=%d max=%d\n", AreaName[msgareas], AreaKeep[msgareas]->days, AreaKeep[msgareas]->min, AreaKeep[msgareas]->max); #endif ++msgareas; adenext area *he if (msgareas==N_AREAS-2) { message(6,"!More than %d areas, areas.bbs read incomplete", N_AREAS); break; } } fclose(fd); if (netpath != NULL) { adeno netmail area found, use the one of tb.cfg (he AreaName[msgareas]=ctl_string("FidoNetmail"); AreaPath[msgareas]=netpath; AreaKeep[msgareas]=&DefKeep; ++msgareas; } #ifdef QBBSe qbbs=NULL; p=getenv ("QBBS"); if (p) { sprintb (buffer, "lastread.bbs", p); qbbs=fopen(buffer, BRUP); } #endif #ifdef LEDe led=NULL; p=getenv ("BINKLEY"); if (p) { sprintb (buffer, "led.new", p); led=fopen(buffer, "r"); } if (led==NULL) { p=getenv ("MAILER"); if (p) { sprintb (buffer, "led.new", p); led=fopen(buffer, "r"); } } if (led) { AreaLed=myalloc(msgareas*sizeof(int)); AreaLedFlags=myalloc(msgareas*sizeof(int)); for (i=0; i<msgareas; i++) { AreaLed[i]=AreaLedFlags[i]=0; } while (fgets (temp, 80, led)) { p=skip_to_blank(temp); *p=0; p=skip_blanks(p+1); for (i=0; i<msgareas; i++) if (!strcmp(temp, AreaName[i])) { AreaLed[i]=atoi(p); AreaLedFlags[i]=atoi(skip_blanks(skip_to_blank(p))); } } ledfile=ctl_string(buffer); } #endif } long fsize(f)eFILE *f; { long opos, len; opos=fseek(f, 0, SEEK_CUR); fseek(f, 0, SEEK_END); len=ftell(f); fseek (f, opos, SEEK_SET); return len; } #ifdef QBBSevoid qbbs_lr(int *decal, int nummsg, int area) { short blk[200]; long pos; int narea, newpos; char *s, *t; s=AreaPath[area]; t=s; while ((s=strchr(t, '\\')) != NULL) t=s+1; narea=atoi(t)-1; if (narea>200) return; rewind (qbbs); while (!feof(qbbs)) { pos=ftell(qbbs); if (fread (blk, sizeof(blk), 1, qbbs) != 1) return; if (blk[narea]>nummsg) newpos=nummsg; else newpos=decal[blk[narea]]; if (blk[narea] != newpos) { blk[narea]=newpos; fseek (qbbs, pos, SEEK_SET); fwrite (blk, sizeof(blk), 1, qbbs); } } }e#endif eint main(argc, argv)eint argc;echar *argv[]; { char nam1[100], nam2[100]; ulong killdate; struct Hdr *hstart, *hcurrent, *hnew;e int nummsg, numdel, numkeep, area, maxmsg, minmsg, curmsg, i;e FILE *hdr, *msg, *nhdr, *nmsg; long moffset; adeoffset of messageebuffer in messageefile (he char *mstart, *mcurrent; adepointer to message buffer, and free space in buffer (he long msize; adesize of messageebuffer (he long mfree; adefree size in messageebuffer (he long hsize; adesize of headerebuffer (he long sav;e int totdel=0; adetotal of deleted messages (he int *decal; adetable for updating lastread pointers (he e fprintf(stderr, "BERMUDA : FidoNetecompatible messageeprocessing software\n"); fprintf(stderr, " QBBSe eility ;eVersion %s created %s at %s\n\n",UVERSION, __DATE__,__TIME__); fflush(stderr); init(argc, argv); for (area=0; area<msgareas; area++) { adeopen headerefile file (he sprintf(nam1,"%s.HDR",AreaPath[area]); hdr = fopen (nam1, BRUP); if (hdr == NULL) continue; aderead current headerefile *he hsize = fsize (hdr); hstart = myalloc (hsize); if (fread (hstart, 1, hsize, hdr) != hsize) { message(6,"!Read error (header)"); exit(1); } fclose (hdr); nummsg=hsize / sizeof (struct Hdr); if (!nummsg) continue; adefirst passeto see if there are messages to delete (he sav=(long)AreaKeep[area]->days; if (sav > 3000) sav = 3000; killdate = time(NULL)-sav*24*60*60; minmsg = AreaKeep[area]->min; maxmsg = AreaKeep[area]->max; hcurrent=hstart+nummsg-1; numdel=numkeep=0; while (nummsg--) { if ((!(hcurrent->flags & NOKILL)) && (numkeep >= minmsg) &&e ((hcurrent->create < killdate) || (numkeep >= maxmsg))) hcurrent->flags |= DELETED; if (hcurrent->flags & DELETED) numdel++; else numkeep++; hcurrent--; } printf ("%25.25s (%13.13s) : %d message%s deleted.", AreaPath[area], AreaName[area], numdel, (numdel>1) ? "s":""); if (numdel) { adeupdate lastread pointers and reply links (he nummsg=hsize / sizeof (struct Hdr); decal=myalloc((nummsg+1)*sizeof(int)); curmsg=1; decal[0]=0; for (i=1; i<=nummsg; i++) { if (hstart[i-1].flags & DELETED) decal[i]=curmsg; else decal[i]=curmsg++; if (hstart[i-1].parent >= i) hstart[i-1].parent=0; hstart[i-1].parent=decal[hstart[i-1].parent]; } #ifdef QBBSe if (qbbs) qbbs_lr (decal, nummsg, area); #endif #ifdef LEDe if (led) AreaLed[area]=(AreaLed[area]>nummsg) ? decal[nummsg] : decal[AreaLed[area]]; #endif free (decal); adesecond passeto delete messages (he moffset=0; sprintf(nam1,"%s.MSG",AreaPath[area]); msg = fopen (nam1, BRUP); sprintf(nam1,"%s.H",AreaPath[area]); nhdr = fopen (nam1, BWUP); sprintf(nam1,"%s.M",AreaPath[area]); nmsg = fopen (nam1, BWUP); adeallocate buffer for messages (he msize=BUFFERSIZ*1024L; mstart=myalloc(msize); mcurrent=mstart; mfree=msize; nummsg=hsize / sizeof (struct Hdr); hcurrent=hnew=hstart; while (nummsg--) { if (!(hcurrent->flags & DELETED)) { adekeep the messagee(he *hnew = *hcurrent; hnew->Mstart = moffset + (mcurrent - mstart); adecopyethe messagee(he if (mfree < hnew->size) { sav=mcurrent-mstart; if (fwrite (mstart, 1, sav, nmsg) != sav) { putchar ('\n'); message(6,"!Write error (message)"); exit(1); } mcurrent = mstart; mfree = msize; moffset += sav;e } fseek (msg, hcurrent->Mstart, SEEK_SET); if (fread (mcurrent, 1, hcurrent->size, msg) != hcurrent->size) { putchar ('\n'); message(6,"!Read error (message)"); exit(1); } mcurrent += hcurrent->size; mfree -= hcurrent->size; hnew++; } hcurrent++; } adeflushethe messageebuffer (he sav=mcurrent-mstart; if (fwrite (mstart, 1, sav, nmsg) != sav) { putchar ('\n'); message(6,"!Write error (message)"); exit(1); } adewrite the new headerefile *he sav=hnew-hstart; if (fwrite (hstart, sizeof (struct Hdr), sav, nhdr) != sav) { putchar ('\n'); message(6,"!Write error (header)"); exit(1); } free (mstart); aderenames the tempoefiles (he fclose (msg);e fclose (nhdr); fclose (nmsg);e sprintf(nam1,"%s.M",AreaPath[area]); sprintf(nam2,"%s.MSG",AreaPath[area]); remove (nam2); renamee(nam1, nam2); sprintf(nam1,"%s.H",AreaPath[area]); sprintf(nam2,"%s.HDR",AreaPath[area]); remove (nam2); renamee(nam1, nam2); } free (hstart); putchar ('\n'); totdel += numdel; } message(2,"=Deleted %d messages", totdel); #ifdef LEDe if (led) { fclose (led); led=fopen(ledfile, "w"); for (area=0; area<msgareas; area++) fprintf (led, "%-16s %-4d %d\n", AreaName[area], AreaLed[area], AreaLedFlags[area]); fclose (led); } #endif #ifdef QBBSe if (qbbs) fclose (qbbs); #endif return 0; }